<?php
/* {
Citru - www.citru.se
See license.txt for copyright and license information.
} */

if(!defined("_CITRU")) {die('This file should not be accessed directly.');}
require_once 'Module.php';

class TextModule extends Module {
	
	protected $moduleTabs = array("view", "edit", "settings", "permissions");
	protected $moduleName = "TextModule";
	protected $instanceName;
	protected $dbModule;
	protected $permissions;
	
	function __construct($instance, $db_module, $permissions) {
		$this->instanceName = $instance;
		$this->dbModule = $db_module;
		$this->permissions = $permissions;
	}
	
	/**
	 * Adds the necessary table for TextModule
	 *
	 * @return void
	 */
	public function installTables() {
		$params = array(	"table" => 'TextModule',
							"columns" => array( array('id', 'int(11) NOT NULL auto_increment'),
							 					array('instance', 'text NOT NULL'),
												array('heading', 'text NOT NULL'),
												array('text', 'mediumtext NOT NULL'),
												array('link', 'text NOT NULL'),
												array('settings', 'text NOT NULL')),
							"primary_key" => 'id');
		if(!$this->dbModule->addTable($params)) {
			throw new Exception('Could not create table for '.$this->moduleName.'.');
		}
		
		// Add global permissions
		$params_perm = array(	'table' => 'Permissions',
        					'set' => array(	'module'=>$this->moduleName,
											'permissions'=>"view=@admin\nedit=@admin\nsettings=@admin\npermissions=@admin"));
        if(!$this->dbModule->insertRow($params_perm)) {
			throw new Exception('Could not create global permissions for '.$this->moduleName.'.');
		}
	}
	
	/**
	 * Returns the content in the TextModule instance
	 *
	 * @return string		html for the content in the text module
	 */
	public function getView() {
		if($this->permissions['view'] != true) { return ''; }
		
		if(!$row = $this->findInstanceRow()) { return "<p>Instance ".$this->instanceName." not found!</p>"; }
		$settings = $this->parseSettings($row['settings']);
		
		$text = $row['text'];
		if($settings['textile'] !== 'false') {
			$textile = new Textile();
			$text = $textile->TextileThis($text);
		} else {
			$text = htmlentities($text);
			$text = str_replace("\n", '<br />', $text);
		}
		
		if(!$hlevel = $settings['headinglevel']) { $hlevel = '2'; }
		
		if($row['heading'] !== '' && $settings['hasheading'] != 'false') { 
			if($settings['headinglink'] == 'true') {
				$heading = '<h'.$hlevel.'><a href="'.$row['link'].'">'.$row['heading'].'</a></h'.$hlevel.'>'."\n"; 
			} else {
				$heading = '<h'.$hlevel.'>'.$row['heading'].'</h'.$hlevel.'>'."\n"; 
			}
		}
		$returnData = $heading.$text;
		return $returnData;
	}
	
	/**
	 * Returns the selected tab of the admin view
	 *
	 * @param string $tab 	selected tab
	 * @return string		html for the selected tab
	 */
	protected function getAdminTab($tab="view") {
		switch($tab) {
			case "edit":
				return $this->getEditForm($message);
			case "settings":
				return $this->getSettingsForm();
			case "permissions":
				return $this->getPermissionsForm();
			default:
				return $this->getView();
		}
	}
	
	/**
	 * Returns a edit-form for the TextModule instance
	 *
	 * @param string $message 		message to present at the bottom of the form
	 * @return string				html for the edit form
	 */
	private function getEditForm($message="") {
		if($this->permissions['edit'] != true) { return ''; }
		
		// Check if the form should be saved first
		if($_POST['instance'] == "TextModule_$this->instanceName" && $_POST['action'] == "edit") {
			if($_POST['new'] == "true") {
				$message = $this->saveFormData(true);
			} else {
				$message = $this->saveFormData(false);
			}
		}
		
		// Get the form data, generate if instance can't be found
		$row = $this->findInstanceRow();
		$settings = $this->parseSettings($row['settings']);
		$new = 'false';
		if(!$row) { 
			$row['heading'] = 'This Textmodule is empty';
			$row['text'] = 'Add some text and click save.';
			$new = 'true';
		}
		
		if($settings['hasheading'] != 'false') {
			$heading = $this->generateForm(array(array('input_text', 'name'=>'heading', 'class'=>'citru_heading', 'value'=>$row['heading'], 'after'=>'<br />')));
		}
		
		if($settings['headinglink'] == 'true') {
			$link = $this->generateForm(array(array('label', 'for'=>'link', 'text'=>'Links to: ', 'class'=>'citru_narrow'),
											  array('input_text', 'name'=>'link', 'class'=>'citru_narrow', 'value'=>$row['link'])));
		}

		$elements = array(array('form_start'),
						  array('hidden_instance'),
						  array('hidden_action', 'value'=>'edit'),
						  array('hidden_new', 'value'=>$new),
						  array('custom', 'data'=>$heading),
						  array('custom', 'data'=>$link),
						  array('textarea', 'name'=>'text', 'text'=>$row['text']),
						  array('footer_start'),
						  array('custom', 'data'=>$message),
						  array('submit', 'value'=>'Save', 'icon'=>'save'),
						  array('footer_end'),
						  array('form_end'));

		$form = $this->generateForm($elements);

		return $form;
	}
	
	/**
	 * Returns a form for editing settings
	 *
	 * @param string $message 		message to present at the bottom of the form
	 * @return string             	html for the settings form
	 */
	private function getSettingsForm($message="") {
		if($this->permissions['settings'] != true) { return ''; }
		
		// Check if settings should be saved first.
		if($_POST['instance'] == "TextModule_$this->instanceName" && $_POST['action'] == "settings") {
			$message = $this->saveSettings();
		}
		
		$row = $this->findSettingsRow();
		$settings = $this->parseSettings($row['settings']);
		// Set defaults if unset
		if($settings['textile'] == '') { $settings['textile'] = 'true'; }
		if($settings['headinglink'] == '') { $settings['headinglink'] = 'false'; }
		if($settings['headinglevel'] == '') { $settings['headinglevel'] = '2'; }
		if($settings['hasheading'] == '') { $settings['hasheading'] = 'true'; }
		
		// Check if heading is active, otherwise disable heading-settings
		if($settings['hasheading'] == 'false') {
			$disable_heading = ' disabled="disabled"';
		}
		
		// Format for use in input/checkbox (true --> checked, false --> '')
		$settings['textile'] = $this->checkboxEncode($settings['textile']);
		$settings['headinglink'] = $this->checkboxEncode($settings['headinglink']);
		$settings['hasheading'] = $this->checkboxEncode($settings['hasheading']);
		
		$elements = array(array('form_start'),
						  array('hidden_instance'),
						  array('hidden_action', 'value'=>'settings'),
						  array('fieldset_start', 'legend'=>'Heading'),
						  array('input_checkbox', 'name'=>'hasheading', 'checked'=>$settings['hasheading'], 'text'=>'This instance has a heading', 'after'=>'<br />'),
						  array('label', 'for'=>'headinglevel', 'text'=>'Heading level: '),
						  array('input_select', 'name'=>'headinglevel', 'options'=>array('1 - Largest', '2 - Very Large', '3 - Large', '4 - Medium', '5 - Small', '6 - Smallest'), 'values'=>array('1','2','3','4','5','6'), 'selected'=>(intval($settings['headinglevel'])-1), 'after'=>'<br />'),
						  array('input_checkbox', 'name'=>'headinglink', 'checked'=>$settings['headinglink'].$disable_heading, 'text'=>'Heading is a link', 'after'=>'<br />'),
						  array('fieldset_end'),
						  array('fieldset_start', 'legend'=>'Textile'),
						  array('input_checkbox', 'name'=>'textile', 'checked'=>$settings['textile'], 'text'=>'Enable Textile formatting in this module', 'after'=>'<br />'),
						  array('fieldset_end'),
						  array('footer_start'),
						  array('custom', 'data'=>$message),
						  array('submit', 'value'=>'Save', 'icon'=>'save'),
						  array('footer_end'),
						  array('form_end'));

		$settings_form = $this->generateForm($elements);
		return $settings_form;
	}
	
	/**
	 * Updates a previous instance from form data
	 *
	 * @param string $new			true if the instance is new 
	 * @return string				a message of how it went
	 */
	private function saveFormData($new = false) {
		if($new == true) { $this->createDataRow(); }
		
		$heading = $_POST['heading'];
		$link = $_POST['link'];		
		$text = $_POST['text'];		
		$params = array(	"table" => "TextModule",
							"condition" =>	array(
											array( "instance", "=", $this->instanceName, "" ) ),
							"set" => array( 	"text" => $text,
												"link" => $link,
												"heading" => $heading ));
																	
		$result = $this->dbModule->updateRow($params);
		
		return '<p class="citru_event">Form data saved.</p>';
	}
	
	/**
	 * Gives a row from the database with the data for an instance
	 *
	 * @return array 				array of row from database. Columns: text, heading, link, settings
	 */
	private function findInstanceRow() {
		$params = array(	"table" => "TextModule",
							"columns" => "text, heading, link, settings",
							"condition" =>	array(
											array( "instance", "=", $this->instanceName, "" ) ));
		
		$row = $this->dbModule->findFirst($params);
		return $row;
	}
	
	/**
	 * Updates the settings of a previous instance from form data
	 *
	 * @return string				a message of how it went
	 */
	private function saveSettings() {
		$textile = $this->checkboxDecode($_POST['textile']);
		$headinglink = $this->checkboxDecode($_POST['headinglink']);
		$headinglevel = $_POST['headinglevel'];
		if(preg_match('/[^0-6]/', $headinglevel)) {
			$headinglevel = 2; // Invalid form data, use default value.
		}
		$hasheading = $this->checkboxDecode($_POST['hasheading']);
		
		// If headingsettings has been disabled, make sure the data for headinglink and headinglevel isn't lost
		$old_row = $this->findSettingsRow();
		$old_settings = $this->parseSettings($old_row['settings']);
		if($old_settings['hasheading'] == 'false') {
			// Let headinglink and headinglevel be what they where
			$settings = 'textile='.$textile."\n".
							'hasheading='.$hasheading."\n".
							'headinglink='.$old_settings['headinglink']."\n".
							'headinglevel='.$old_settings['headinglevel']."\n";
		} else {
			$settings = 'textile='.$textile."\n".
							'hasheading='.$hasheading."\n".
							'headinglink='.$headinglink."\n".
							'headinglevel='.$headinglevel."\n";
		}
		
		
		$params = array(	"table" => "TextModule",
							"condition" =>	array(
											array( "instance", "=", $this->instanceName, "" )),
							"set" => array( "settings" => $settings ));
																	
		$result = $this->dbModule->updateRow($params);
		
		return '<p class="citru_event">Settings saved.</p>';
	}
	
}

?>
